/*
 *  author: Honrun
 */
#include "stdint.h"
#include "stdio.h"
#include "gd32w51x.h"
#include "DevicesList.h"
#include "DevicesTime.h"
#include "DevicesSoftTimer.h"



/* 软件定时器状态机的头节点 */
ListType g_typeListSoftTimerExeHead = {&g_typeListSoftTimerExeHead, &g_typeListSoftTimerExeHead, LIST_VALUE_MAX, NULL};
ListType g_typeListSoftTimerReadyHead = {&g_typeListSoftTimerReadyHead, &g_typeListSoftTimerReadyHead, LIST_VALUE_MAX, NULL};
ListType g_typeListSoftTimerDelHead = {&g_typeListSoftTimerDelHead, &g_typeListSoftTimerDelHead, LIST_VALUE_MAX, NULL};



int8_t cSoftTimerSet(SoftTimerTypeDef *ptypeTimer, int64_t lTime, SoftTimerStateEnum state)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->timeStop = lSoftTimerGetNow() + lTime;
    ptypeTimer->timeDuration = lTime;
    ptypeTimer->state = state;

    return 0;
}

int8_t cSoftTimerReset(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    cSoftTimerSet(ptypeTimer, ptypeTimer->timeDuration, ptypeTimer->state | softTimerOpen);

    return 0;
}

int8_t cSoftTimerReload(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->timeStop += ptypeTimer->timeDuration;
    ptypeTimer->state |= softTimerOpen;

    return 0;
}

int8_t cSoftTimerOpen(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state |= softTimerOpen;

    return 0;
}

int8_t cSoftTimerClose(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state &= ~softTimerOpen;

    return 0;
}

int8_t cSoftTimerSetState(SoftTimerTypeDef *ptypeTimer, SoftTimerStateEnum enumState)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state = enumState;

    /* 设置为本次立即触发 */
    if(enumState & softTimerOver)
        ptypeTimer->timeStop = lSoftTimerGetNow();

    return 0;
}

SoftTimerStateEnum enumSoftTimerGetState(SoftTimerTypeDef *ptypeTimer)
{
    int64_t ulTimeNow = 0;

    if(ptypeTimer == NULL)
        return softTimerError;

    if((ptypeTimer->state & softTimerOpen) == 0)
        return softTimerClose;

    ulTimeNow = lSoftTimerGetNow();

    if(ulTimeNow >= (ptypeTimer->timeStop))
        return softTimerOver;

    return softTimerOpen;
}

/* 单位us */
int64_t lSoftTimerGetNow(void)
{
    int64_t lTimeStamp = 0;

    lTimeStamp = lTimeGetStamp();

    return lTimeStamp;
}







int8_t cSoftTimerCreate(SoftTimerTaskTypeDef *ptypeTimer, int64_t lTime, SoftTimerStateEnum state, void (*vCallbackFunction)(void *pvHandle))
{
    int8_t cError = 0;

    if(ptypeTimer == NULL)
        return -1;

    cError |= cSoftTimerSetUs(&(ptypeTimer->timer), lTime, state);

    cError |= cListInit(&(ptypeTimer->typeListExe), ptypeTimer->timer.timeStop);

    /* 插入 */
    cError |= cListInsertEnd(&g_typeListSoftTimerReadyHead, &(ptypeTimer->typeListExe));

    ptypeTimer->typeListExe.pElement = ptypeTimer;
    ptypeTimer->typeListDel.pElement = ptypeTimer;

    ptypeTimer->vCallbackFunction = vCallbackFunction;

    return cError;
}

int8_t cSoftTimerRemove(SoftTimerTaskTypeDef *ptypeTimer)
{
    int8_t cError = 0;

    if(ptypeTimer == NULL)
        return -1;

    /* 插入 */
    cError |= cListInsertEnd(&g_typeListSoftTimerDelHead, &(ptypeTimer->typeListDel));

    return cError;
}

int8_t cSoftTimerMachine(void)
{
    ListType *ptypeListNow = NULL;
    SoftTimerTaskTypeDef *ptypeTimerNow = NULL;
    int8_t cError = 0;

    /* 把就绪的插入 */
    for(ptypeListNow = g_typeListSoftTimerReadyHead.pNext; ptypeListNow != &g_typeListSoftTimerReadyHead; ptypeListNow = g_typeListSoftTimerReadyHead.pNext)
    {
        cError |= cListRemove(ptypeListNow);

        /* 按顺序插入 */
        cError |= cListInsert(&g_typeListSoftTimerExeHead, ptypeListNow);
    }


    /* 把要删除的移除 */
    for(ptypeListNow = g_typeListSoftTimerDelHead.pNext; ptypeListNow != &g_typeListSoftTimerDelHead; ptypeListNow = g_typeListSoftTimerDelHead.pNext)
    {
        cError |= cListRemove(ptypeListNow);

        ptypeTimerNow = ptypeListNow->pElement;
        cError |= cListRemove(&(ptypeTimerNow->typeListExe));
    }


    /* 查询链表第一个元素是否到期 */
    ptypeTimerNow = g_typeListSoftTimerExeHead.pNext->pElement;
    while(enumSoftTimerGetState(&(ptypeTimerNow->timer)) == softTimerOver)
    {
        /* 回调函数 */
        if(ptypeTimerNow->vCallbackFunction != NULL)
        {
            ptypeTimerNow->vCallbackFunction(ptypeTimerNow);
        }

        /* 移出链表 */
        cError |= cListRemove(&(ptypeTimerNow->typeListExe));

        /* 重复计时 */
        if(ptypeTimerNow->timer.state & softTimerCircular)
        {
            cError |= cSoftTimerReload(&(ptypeTimerNow->timer));

            cError |= cListInit(&(ptypeTimerNow->typeListExe), ptypeTimerNow->timer.timeStop);

            /* 按顺序插入 */
            cError |= cListInsert(&g_typeListSoftTimerExeHead, &(ptypeTimerNow->typeListExe));
        }
        /* 单次计时 */
        else
            cError |= cSoftTimerClose(&(ptypeTimerNow->timer));

        /* 把指针再次指令链表第一个元素（第一个元素总是最早到期） */
        ptypeTimerNow = g_typeListSoftTimerExeHead.pNext->pElement;
    }

    return cError;
}
